package com.itlong.cloud.operate.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Joiner;
import com.itlong.cloud.POJO.DTO.property.PhoneNumAttributionGroundDTO;
import com.itlong.cloud.POJO.PO.DeviceBusinessChangeLogPO;
import com.itlong.cloud.POJO.PO.RoomInfoPO;
import com.itlong.cloud.POJO.VO.operate.OperateAddressVO;
import com.itlong.cloud.POJO.VO.operate.OperateAreaAddressVO;
import com.itlong.cloud.POJO.VO.operate.OperateCountryAddressVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.enumerate.SmartCommunityEnum;
import com.itlong.cloud.operate.dao.IOperateAddressManageDao;
import com.itlong.cloud.operate.dao.IOperateProjectDao;
import com.itlong.cloud.operate.service.IOperateAddressManageService;
import com.itlong.cloud.property.dao.IPropertyRoomInfoDao;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.phonenumber.PhoneNoHandlerUtil;
import com.itlong.cloud.utils.words.NumberHandlerUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;


/**
 * <desc>
 *      运营—获取国家和区域地址信息。
 * <desc/>
 *
 * @createDate 2017/10/23.
 */
@Service
public class IOperateAddressManageServiceImpl implements IOperateAddressManageService {

    private static final Logger LOG = LoggerFactory.getLogger(IOperateAddressManageServiceImpl.class);

    @Autowired
    MessageSender messageSender;

    @Autowired
    IOperateAddressManageDao iOperateAddressManageDao;

    @Autowired
    IOperateProjectDao iOperateProjectDao;

    @Autowired
    IPropertyRoomInfoDao iPropertyRoomInfoDao;

    /**
     * <desc>
     *      获取国家信息列表。
     * <desc/>
     *
     * @param
     * @return
     * @author shengen.T
     * @createDate 2017/10/23
     */
    @Override
    public List<OperateCountryAddressVO> getCountryList() throws Exception{
        List<OperateCountryAddressVO>  countryList = iOperateAddressManageDao.getCountry();
        return countryList;
    }

    /**
     * <desc>
     *      获取区域信息列表。
     * <desc/>
     *
     * @param  countryId 国家ID
     * @return
     * @author shengen.T
     * @createDate 2017/10/23
     */
    @Override
    public List<OperateAreaAddressVO> getAreaList(String countryId) throws Exception{
        List<OperateAreaAddressVO> areaList = iOperateAddressManageDao.getArea(countryId);
        return areaList;
    }

    /**
     * <desc>
     * 获取某个地址的直接下属地址
     * <desc/>
     *
     * @param parentAddressId 父地址id
     * @return
     * @author Chunjian.G
     * @createDate 2017-12-05
     */
    @Override
    public List<OperateAddressVO> getAddressList(String parentAddressId) throws Exception {
        List<OperateAddressVO> addrs = iOperateAddressManageDao.getAddressList(parentAddressId);
        if (addrs != null && !addrs.isEmpty()){
            String[] addrIds = new String[addrs.size()];
            for (int i = 0; i < addrIds.length; i++){
                addrIds[i] = addrs.get(i).getAddressId();
            }
            List<IOperateAddressManageDao.SubAddressCount> subAddrCounts =
                    iOperateAddressManageDao.getSubAddressCount(addrIds);

            addrs.forEach(a->{
                a.setHasChild(0);
                if (subAddrCounts != null){
                    for (IOperateAddressManageDao.SubAddressCount count: subAddrCounts){
                        if (a.getAddressId().equals(count.getParentAddressId())){
                            a.setHasChild(NumberHandlerUtil.isGreaterThan(count.getCount(), 0) ? 1:0);
                            break;
                        }
                    }
                }
            });
        }
        return addrs;
    }

    /**
     * <desc>
     *      处理手机号码归属地，+0 or -0
     * </desc>
     *
     * @param projectId 项目id
     * @return 处理的房间数
     * @author wangzhi
     * @createDate 2018-04-26
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer handlePhoneNoAttributionGround(String projectId) throws Exception {
        Date nowTime = new Date();
        int intRes = 0;
        List<RoomInfoPO> roomInfoPOS = iPropertyRoomInfoDao.getAllRoomInfoByProject(projectId);
        String projectCityName = iOperateProjectDao.getProjectCityName(projectId);
        List<Map<String,Object>> batchParams = new ArrayList<>();
        for (RoomInfoPO roomInfoPO:roomInfoPOS){
            if (StringUtils.isNotBlank(roomInfoPO.getPhoneNo())) {
                String phoneNo = PhoneNoHandlerUtil.handlerPhoneNoLocationAdd0OrSub0(projectCityName,roomInfoPO.getPhoneNo());
                roomInfoPO.setPhoneNo(phoneNo);
                roomInfoPO.setUpdateTime(nowTime);
                batchParams.add(SqlUtil.durableData(roomInfoPO, PlatformConstants.TABLE_UPDATE));
            }
        }
        if (!batchParams.isEmpty()) {
            intRes = iPropertyRoomInfoDao.batchUpdate(batchParams);
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("projectId", projectId);
        DeviceBusinessChangeLogPO deviceBusinessChangeLogPO = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_FULL, jsonObject, projectId);
        List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
        deviceBusinessChangeLogPOS.add(deviceBusinessChangeLogPO);
        JSONObject dataJs = new JSONObject();
        dataJs.put("data", deviceBusinessChangeLogPOS);
        //云对讲业务指令
        messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);

        return intRes;
    }

    /**
     * <desc>
     *      处理手机号码归属地，异地手机号会在前面加0
     * </desc>
     *
     * @param  projectId 项目编号
     * @param  phoneNums 待处理的手机号码列表，逗号分隔
     * @return 已处理的手机号码
     * @author wangzhi
     * @createDate 2018-04-26
     */
    private String dealWithPhoneNoAttributionGround(String projectId,String phoneNums){

        String resultPhoneNo = phoneNums;

        if (StringUtils.isBlank(projectId) || StringUtils.isBlank(phoneNums)){
            return resultPhoneNo;
        }

        try {
            String projectCityName = iOperateProjectDao.getProjectCityName(projectId);
            if (StringUtils.isBlank(projectCityName)){
                return resultPhoneNo;
            }

            List<String> phoneList =  Arrays.asList(phoneNums.split(","));
            List<String> phoneResult = new ArrayList<>();
            for (String onePhoneNum:phoneList){
                String phoneCityName = this.getPhoneNumCity(onePhoneNum);
                if (StringUtils.isBlank(phoneCityName)){
                    phoneResult.add(onePhoneNum);
                    continue;
                }
                boolean isLocalPhoneNum = projectCityName.contains(phoneCityName);
                String onePhoneResult = onePhoneNum;
                if (!isLocalPhoneNum){ //如果不是本地手机，首位加0
                    onePhoneResult  = String.format("0%s",onePhoneNum.replaceAll("^(0+)", ""));
                } else{ //如果是本地手机，取消首位加0
                    onePhoneResult  = onePhoneNum.replaceAll("^(0+)", "");
                }
                phoneResult.add(onePhoneResult);
            }
            if (!phoneList.isEmpty()){
                resultPhoneNo =  Joiner.on(",").join(phoneResult);
            }


        } catch (Exception e) {
            LOG.error(String.format("处理异地手机号码：%s失败",phoneNums),e);
            return resultPhoneNo;
        }

        return resultPhoneNo;

    }

    /**
     * <desc>
     *    //向淘宝获取电话号码归属地.
     *    向已购买的接口获取更精确的号码归属地
     *    已提取在工具类PhoneNoHandlerUtil，此方法无用
     * </desc>
     *
     * @param  phoneNum 电话号码
     * @return 电话号码归属地名称
     * @author LewisLouis
     * @createDate 2018-01-27
     */
    private String getPhoneNumCity(String phoneNum){
        String phoneCityName = "";
        String checkPhoneNum = phoneNum.replaceAll("^(0+)", ""); //去掉首位可能存在的0
//        String url = "https://tcc.taobao.com/cc/json/mobile_tel_segment.htm";
//        String arg = String.format("tel=%s",checkPhoneNum);
        String host = "https://api04.aliyun.venuscn.com";
        String path = "/mobile";
        String method = "GET";
        String appcode = "c1924a31f90e4259a8062060a9ad7c0d";
        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", "APPCODE " + appcode);
        Map<String, String> querys = new HashMap<>();
        querys.put("mobile",checkPhoneNum);

        try {
//            String result =  httpGet(url,arg);
            HttpResponse response = HttpProtocolUtil.doGet(host, path, method, headers, querys);
//            if (StringUtils.isBlank(result)){
//                return phoneCityName;
//            }
//            PhoneZoneResultVO zoneResultVO = JSONObject.parseObject(result,PhoneZoneResultVO.class);
//            if ((null == zoneResultVO) || (StringUtils.isBlank(zoneResultVO.getProvince()))){
//                LOG.error(String.format("获取手机号码:%s归属地失败",phoneNum));
//                return province;
//            }
//            phoneCityName = getProvinceNameByResponeMsg(result);
//            if (StringUtils.isBlank(phoneCityName)) {
//                LOG.error(String.format("从http返回报文:%s 中解析手机号码:%s归属地失败", result, phoneNum));
//                return phoneCityName;
//            }
            if (response != null && response.getEntity() != null) {
                Map<String, Object> jsonToMap = JsonUtil.JsonToMap(EntityUtils.toString(response.getEntity()));
                if (jsonToMap != null && !jsonToMap.isEmpty()){
                    PhoneNumAttributionGroundDTO phoneNumAttributionGroundDTO = JsonUtil.toObject(jsonToMap.get("data").toString(), PhoneNumAttributionGroundDTO.class);
                    if (StringUtils.isNotBlank(phoneNumAttributionGroundDTO.getCity())){
                        phoneCityName = phoneNumAttributionGroundDTO.getCity();
                    }
                    return phoneCityName;
                }
            }
            LOG.info("获取手机号码归属地失败！");

        } catch (Exception e) {
            LOG.error(String.format("获取手机号码:%s归属地异常",phoneNum),e);
            return phoneCityName;
        }
        return phoneCityName;
    }

    /**
     * <desc>
     *    从http返回报文中解析出省级区域名称.
     * </desc>
     *
     * @param  * @param null
     * @return xx
     * @author LewisLouis
     * @createDate 2018-01-27
     */
    private String getProvinceNameByResponeMsg(String responseMsg){

        String provinceName = "";
        if (StringUtils.isBlank(responseMsg)){
            return provinceName;
        }

        String provinceNameTag = "province";
        int provinceNamePos = responseMsg.indexOf(provinceNameTag);
        if (provinceNamePos < 0){
            return provinceName;
        }
        String tmpMsg = StringHandlerUtil.copySubStr(responseMsg,provinceNamePos,responseMsg.length());
        int commaPos = tmpMsg.indexOf(",");
        if (commaPos < 0){
            return tmpMsg;
        }
        provinceName = StringHandlerUtil.copySubStr(tmpMsg,provinceNameTag.length()+1,commaPos - provinceNameTag.length() - 2);
        provinceName = provinceName.replaceAll("'", ""); //去掉首位可能存在的0
        return provinceName;

    }

    /**
     * <desc>
     *    Http Get信息.注意，本接口编码为GBK，为向淘宝获取电话号码归属地专用
     * </desc>
     *
     * @param httpUrl 请求url
     * @param httpUrl 请求参数
     * @return get返回值，若失败，则返回null
     * @author LewisLouis
     * @createDate 2018-01-27
     */
    private String httpGet(String httpUrl, String httpArg)  {
        BufferedReader reader = null;
        String result = null;
        StringBuffer sbf = new StringBuffer();
        httpUrl = httpUrl + "?" + httpArg;
        try {
            URL url = new URL(httpUrl);
            HttpURLConnection connection = (HttpURLConnection) url
                    .openConnection();
            connection.setRequestMethod("GET");
            // 填入apikey到HTTP header
//            connection.setRequestProperty("apikey",  "您自己的apikey");
            connection.connect();
            InputStream is = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is, "GBK"));
            String strRead = null;
            while ((strRead = reader.readLine()) != null) {
                sbf.append(strRead);
                sbf.append("\r\n");
            }
            reader.close();
            result = sbf.toString();
        } catch (IOException e) {
            LOG.error(String.format("Http请求:%s,参数:%s 失败","",""),e);
        }
        return result;
    }

}
